package com.sfzlot.dev.netty.server.server;

import com.sfzlot.dev.netty.server.client.handler.ClientHandler;
import com.sfzlot.dev.netty.server.server.decode.Decoder;
import com.sfzlot.dev.netty.server.server.encode.Encoder;
import com.sfzlot.dev.netty.server.server.handler.ServerHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.AdaptiveRecvByteBufAllocator;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.handler.timeout.IdleStateHandler;

/**
 * Created by ASUS on 2017/5/27.
 */
@Component
public class SflotServer {
    final static Logger logger = LoggerFactory.getLogger(SflotServer.class);

    public void bind(int port) throws InterruptedException {
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        ServerBootstrap serverBootstrap = new ServerBootstrap();
        try {
            serverBootstrap
            .group(bossGroup,workerGroup)
            .channel(NioServerSocketChannel.class)
            .option(ChannelOption.SO_BACKLOG,100)
            .childOption(ChannelOption.RCVBUF_ALLOCATOR, new AdaptiveRecvByteBufAllocator(64, 1024, 65536))
            .handler(new LoggingHandler(LogLevel.INFO))
            .childHandler(new ChildChannelHandler());
    		ChannelFuture channelFuture = serverBootstrap.bind(port).sync();
    		channelFuture.channel().closeFuture().sync();
        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
            logger.info("netty服务启动！！端口：{}.", port);
        }
    }
	
	private class ChildChannelHandler extends ChannelInitializer<SocketChannel>{
        @Override
        protected  void initChannel(SocketChannel arg0)throws Exception{
        	arg0.pipeline().addLast(new Decoder(1024, 28, 2, 0, 0, false));
            arg0.pipeline().addLast(new Encoder());
        	arg0.pipeline().addLast(new IdleStateHandler(60, 0, 0));//60S没有读到数据，断开连接
            arg0.pipeline().addLast(new ServerHandler());
        }
    }
}
